#include "WorkerThread.h"
#include "Action.h"
#include "ActionDispatcher.h"


void WorkerThread::CleanupHandler(void* ptr)
{
    //LogInfoToFile("WorkerThread::CleanupHandler");
}

void WorkerThread::Run()
{
    int rc=0, oldState=0;
    bool resume = true;
    Job* currentJob;

    sigset_t mask;
    if (0 != sigfillset(&mask)) {
        //logError("WorkerThread sigfillset failed!");
    }

    if (0 != pthread_sigmask(SIG_SETMASK, &mask, NULL)) {
        //logError("WorkerThread pthread_sigmask failed!");
    }

    pthread_cleanup_push(CleanupHandler, this);

    for ( ; ; )
    {
        m_mutex.Lock();
        while (m_pJob == NULL)
        {
            m_cond.Wait(&m_mutex);
        }
        m_mutex.Unlock();

        rc = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState);

        m_pJob->Run(m_pJob->GetData());

        m_pJob->SetData(NULL);
        m_pJob->SetWorkThread(NULL);

        Action* pActtion = new Action(Action::JOBDONE, m_pJob);

        if (m_pJob->IsDone())
        {
            m_pJob->Destory();
            m_pJob = NULL;
            pActtion->SetEndFlag(true);
        }

        ActionDispatcher::GetInstance()->Assign(pActtion);

        m_pJob = NULL;
        m_pThreadPool->MoveToIdleList(this);

        rc = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,&oldState);
        pthread_testcancel(); //cancel-point
    }

    pthread_cleanup_pop(1);
}

void WorkerThread::SetJob(Job* pJob)
{
    m_mutex.Lock();
    m_pJob = pJob;
    m_cond.Signal();
    m_mutex.Unlock();
}

Job* WorkerThread::GetJob()
{
    Job* pJob = NULL;
    m_mutex.Lock();
    pJob = m_pJob;
    m_mutex.Unlock();
    return pJob;
}

void WorkerThread::SetThreadPool(ThreadPool* pThreadPool)
{
    m_mutex.Lock();
    m_pThreadPool = pThreadPool;
    m_mutex.Unlock();
}


